/**
 ******************************************************************************
 * @file      AFN10.c
 * @brief     C Source file of AFN10.c.
 * @details   This file including all API functions's implement of AFN10.c.
 * @copyright
 ******************************************************************************
 */

/*-----------------------------------------------------------------------------
 Section: Includes
 ----------------------------------------------------------------------------*/
#include <stdio.h>

#include "../GDW1376_2.h"
#include "lib.h"
#include "maths.h"
#include "types.h"

/*-----------------------------------------------------------------------------
 Section: Type Definitions
 ----------------------------------------------------------------------------*/
/* NONE */

/*-----------------------------------------------------------------------------
 Section: Constant Definitions
 ----------------------------------------------------------------------------*/
/* NONE */

/*-----------------------------------------------------------------------------
 Section: Global Variables
 ----------------------------------------------------------------------------*/
/* NONE */

/*-----------------------------------------------------------------------------
 Section: Local Variables
 ----------------------------------------------------------------------------*/
/* NONE */

/*-----------------------------------------------------------------------------
 Section: Local Function Prototypes
 ----------------------------------------------------------------------------*/
/* NONE */

/*-----------------------------------------------------------------------------
 Section: Global Function Prototypes
 ----------------------------------------------------------------------------*/
/* NONE */

/*-----------------------------------------------------------------------------
 Section: Function Definitions
 ----------------------------------------------------------------------------*/
#include <stdlib.h>
#include <string.h>
#ifdef BSWAP_16
#undef BSWAP_16
#endif

#ifdef BSWAP_8
#undef BSWAP_8
#endif
#define BSWAP_8(x) ((x)&0xff)
#define BSWAP_16(x) ((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8))

/**
 ******************************************************************************
 * @brief   输出从节点数量解析字符串
 * @param[in]   dir         : 传输方向:1上行(模块->集中器)" 0下行(集中器->模块)
 * @param[in]  *pin         : 输入报文
 * @param[in]   len         : 应用层报文长度
 * @param[in]  *pcb         : 回调函数
 * @param[in]  *pline_head  : 每行起始填充字符串
 * @param[in]  *pline_end   : 每行结束填充字符串
 *
 * @return  0 : 解析成功
 * @return -1 : 解析失败
 ******************************************************************************
 */
static int AFN10_FN01(unsigned char dir, const unsigned char *pin, int len,
                      pcallback pcb, const char *pline_head,
                      const char *pline_end) {
  pcb(pline_head);
  pcb("从节点数量");
  pcb(pline_end);
  if (dir == 0)  //下行
  {
    pcb(pline_head);
    pcb("无数据单元");
    pcb(pline_end);
  } else  //上行
  {
    CHK_APP_LEN(len, 4);
    sprintf(buf, "%s从节点总数量[%02X %02X]:%d%s", pline_head, pin[0], pin[1],
            pin[0] | ((int)pin[1] << 8), pline_end);
    pcb(buf);
    sprintf(buf, "%s路由支持最大从节点数量[%02x %02x]:%d%s", pline_head, pin[2],
            pin[3], pin[2] | ((int)pin[3] << 8), pline_end);
    pcb(buf);
  }

  return 0;
}

/**
 ******************************************************************************
 * @brief   输出从节点信息解析字符串
 * @param[in]   dir         : 传输方向:1上行(模块->集中器)" 0下行(集中器->模块)
 * @param[in]  *pin         : 输入报文
 * @param[in]   len         : 应用层报文长度
 * @param[in]  *pcb         : 回调函数
 * @param[in]  *pline_head  : 每行起始填充字符串
 * @param[in]  *pline_end   : 每行结束填充字符串
 *
 * @return  0 : 解析成功
 * @return -1 : 解析失败
 ******************************************************************************
 */
static int AFN10_FN02(unsigned char dir, const unsigned char *pin, int len,
                      pcallback pcb, const char *pline_head,
                      const char *pline_end) {
  int i;
  const char *const type[] = {
      "透明传输",
      "DL/T645-1997",
      "DL/T645-2007",
      "DL/T698.45",
  };

  pcb(pline_head);
  pcb("从节点信息");
  pcb(pline_end);
  if (dir == 0)  //下行
  {
    sprintf(buf, "%s从节点起始序号[%02X %02X]:%d%s", pline_head, pin[0], pin[1],
            pin[0] | ((int)pin[1] << 8), pline_end);
    pcb(buf);
    sprintf(buf, "%s从节点数量[%02x]:%d%s", pline_head, pin[2], pin[2],
            pline_end);
    pcb(buf);
  } else  //上行
  {
    sprintf(buf, "%s从节点总数量[%02X %02X]:%d%s", pline_head, pin[0], pin[1],
            pin[0] | ((int)pin[1] << 8), pline_end);
    pcb(buf);
    sprintf(buf, "%s本次应答的从节点数量:%d%s", pline_head, pin[2], pline_end);
    pcb(buf);
    if (len < (pin[2] * 8 + 3)) {
      sprintf(buf, "%s输入报文长度不足解析失败!%s", pline_head, pline_end);
      pcb(buf);
      return -1;
    }

    for (i = 0; i < pin[2]; i++) {
      sprintf(buf, "%s从节点%d地址:[%02X %02X %02X %02X %02X %02X]%s",
              pline_head, i, pin[i * 8 + 3], pin[i * 8 + 4], pin[i * 8 + 5],
              pin[i * 8 + 6], pin[i * 8 + 7], pin[i * 8 + 8], pline_end);
      pcb(buf);

      sprintf(buf, "%s中继级别:%d%s", pline_head, pin[i * 8 + 9] & 0x0f,
              pline_end);
      pcb(buf);
      sprintf(buf, "%s侦听信号品质:%d%s", pline_head, pin[i * 8 + 9] >> 4,
              pline_end);
      pcb(buf);
      sprintf(buf, "%s相位[%d]:%s%s", pline_head, pin[i * 8 + 10] & 0x07,
              "(D8 D9 D10置\"1\"依次表示第1 2 3相)", pline_end);
      pcb(buf);
      sprintf(buf, "%s通信协议类型[%d]:%s%s", pline_head,
              (pin[i * 8 + 10] >> 3) & 0x07,
              (((pin[i * 8 + 10] >> 3) & 0x07) < 4)
                  ? type[(pin[i * 8 + 10] >> 3) & 0x07]
                  : "保留",
              pline_end);
      pcb(buf);
    }
  }

  return 0;
}

/**
 ******************************************************************************
 * @brief   输出指定从节点的上一级中继路由信息解析字符串
 * @param[in]   dir         : 传输方向:1上行(模块->集中器)" 0下行(集中器->模块)
 * @param[in]  *pin         : 输入报文
 * @param[in]   len         : 应用层报文长度
 * @param[in]  *pcb         : 回调函数
 * @param[in]  *pline_head  : 每行起始填充字符串
 * @param[in]  *pline_end   : 每行结束填充字符串
 *
 * @return  0 : 解析成功
 * @return -1 : 解析失败
 ******************************************************************************
 */
static int AFN10_FN03(unsigned char dir, const unsigned char *pin, int len,
                      pcallback pcb, const char *pline_head,
                      const char *pline_end) {
  int i;
  const char *const type[] = {
      "透明传输",
      "DL/T645-1997",
      "DL/T645-2007",
      "DL/T698.45",
  };

  pcb(pline_head);
  pcb("指定从节点的上一级中继路由信息");
  pcb(pline_end);
  if (dir == 0)  //下行
  {
    CHK_APP_LEN(len, 6);
    sprintf(buf, "%s从节点地址:[%02X %02X %02X %02X %02X %02X]%s", pline_head,
            pin[0], pin[1], pin[2], pin[3], pin[4], pin[5], pline_end);
    pcb(buf);
  } else  //上行
  {
    sprintf(buf, "%s提供路由的从节点总数量:%d%s", pline_head, pin[0],
            pline_end);
    pcb(buf);
    if (len < (pin[0] * 8 + 1)) {
      sprintf(buf, "%s输入报文长度不足解析失败!%s", pline_head, pline_end);
      pcb(buf);
      return -1;
    }

    for (i = 0; i < pin[0]; i++) {
      sprintf(buf, "%s提供路由的从节点%d地址:[%02X %02X %02X %02X %02X %02X]%s",
              pline_head, i, pin[i * 8 + 1], pin[i * 8 + 2], pin[i * 8 + 3],
              pin[i * 8 + 4], pin[i * 8 + 5], pin[i * 8 + 6], pline_end);
      pcb(buf);

      sprintf(buf, "%s中继级别:%d%s", pline_head, pin[i * 8 + 7] & 0x0f,
              pline_end);
      pcb(buf);
      sprintf(buf, "%s侦听信号品质:%d%s", pline_head, pin[i * 8 + 7] >> 4,
              pline_end);
      pcb(buf);
      sprintf(buf, "%s相位[%d]:%s%s", pline_head, pin[i * 8 + 8] & 0x07,
              "(D8 D9 D10置\"1\"依次表示第1 2 3相)", pline_end);
      pcb(buf);
      sprintf(buf, "%s通信协议类型[%d]:%s%s", pline_head,
              (pin[i * 8 + 8] >> 3) & 0x07,
              (((pin[i * 8 + 8] >> 3) & 0x07) < 4)
                  ? type[(pin[i * 8 + 8] >> 3) & 0x07]
                  : "保留",
              pline_end);
      pcb(buf);
    }
  }

  return 0;
}

/**
 ******************************************************************************
 * @brief   输出路由运行状态解析字符串
 * @param[in]   dir         : 传输方向:1上行(模块->集中器)" 0下行(集中器->模块)
 * @param[in]  *pin         : 输入报文
 * @param[in]   len         : 应用层报文长度
 * @param[in]  *pcb         : 回调函数
 * @param[in]  *pline_head  : 每行起始填充字符串
 * @param[in]  *pline_end   : 每行结束填充字符串
 *
 * @return  0 : 解析成功
 * @return -1 : 解析失败
 ******************************************************************************
 */
static int AFN10_FN04(unsigned char dir, const unsigned char *pin, int len,
                      pcallback pcb, const char *pline_head,
                      const char *pline_end) {
  int i;
  const char *const work_step[] = {
      "备用",  // 0
      "初始状态",     "值抄",       "中继", "监控状态",
      "广播状态",  // 5
      "广播招读电表", "读侦听信息", "空闲",
  };

  pcb(pline_head);
  pcb("路由运行状态");
  pcb(pline_end);
  if (dir == 0)  //下行
  {
    pcb(pline_head);
    pcb("无数据单元");
    pcb(pline_end);
  } else  //上行
  {
    CHK_APP_LEN(len, 16);
    sprintf(buf, "%s 运行状态字[%02x]:%d%s", pline_head, pin[0], pin[0],
            pline_end);
    pcb(buf);
    sprintf(buf, "%s 路由完成标志[%d]:路由学习%s完成%s", pline_head,
            BITS(pin[0], 0), BITS(pin[0], 0) ? "" : "未", pline_end);
    pcb(buf);
    sprintf(buf, "%s 工作标志[%d]:%s工作%s", pline_head, BITS(pin[0], 1),
            BITS(pin[0], 0) ? "正在" : "停止", pline_end);
    pcb(buf);
    sprintf(buf, "%s 上报事件标志[%d]:%s从节点上报事件%s", pline_head,
            BITS(pin[0], 2), BITS(pin[0], 2) ? "有" : "无", pline_end);
    pcb(buf);
    sprintf(buf, "%s 纠错编码[%d]:%s", pline_head, pin[0] >> 4, pline_end);
    pcb(buf);

    sprintf(buf, "%s 从节点总数量[%02X %02X]:%d%s", pline_head, pin[1], pin[2],
            pin[1] | ((int)pin[2] << 8), pline_end);
    pcb(buf);
    sprintf(buf, "%s 已抄从节点数量[%02X %02X]:%d%s", pline_head, pin[3],
            pin[4], pin[3] | ((int)pin[4] << 8), pline_end);
    pcb(buf);
    sprintf(buf, "%s 中继抄到从节点数量[%02X %02X]:%d%s", pline_head, pin[5],
            pin[6], pin[5] | ((int)pin[6] << 8), pline_end);
    pcb(buf);
    sprintf(buf, "%s 工作开关[%02x]:%d%s", pline_head, pin[7], pin[7],
            pline_end);
    pcb(buf);
    sprintf(buf, "%s 工作状态[%d]:%s%s", pline_head, BITS(pin[7], 0),
            BITS(pin[7], 0) ? "学习" : "抄表", pline_end);
    pcb(buf);
    sprintf(buf, "%s 注册允许状态[%d]:%s允许%s", pline_head, BITS(pin[7], 1),
            BITS(pin[7], 1) ? "" : "不", pline_end);
    pcb(buf);

    sprintf(buf, "%s 通信速率[%02X %02X]:%d%s", pline_head, pin[8], pin[9],
            pin[8] | ((int)pin[9] << 8), pline_end);
    pcb(buf);

    for (i = 1; i < 4; i++) {
      sprintf(buf, "%s 第%d中继级别[%02x]:%d%s", pline_head, i, pin[9 + i],
              pin[9 + i] & 0x0f, pline_end);
      pcb(buf);
    }

    for (i = 1; i < 4; i++) {
      sprintf(buf, "%s 第%d工作步骤[%02x]:%s%s", pline_head, i, pin[12 + i],
              (pin[12 + i] < 9) ? work_step[pin[12 + i]] : "备用", pline_end);
      pcb(buf);
    }
  }

  return 0;
}

/**
 ******************************************************************************
 * @brief   输出未抄读成功的从节点信息解析字符串
 * @param[in]   dir         : 传输方向:1上行(模块->集中器)" 0下行(集中器->模块)
 * @param[in]  *pin         : 输入报文
 * @param[in]   len         : 应用层报文长度
 * @param[in]  *pcb         : 回调函数
 * @param[in]  *pline_head  : 每行起始填充字符串
 * @param[in]  *pline_end   : 每行结束填充字符串
 *
 * @return  0 : 解析成功
 * @return -1 : 解析失败
 ******************************************************************************
 */
static int AFN10_FN05(unsigned char dir, const unsigned char *pin, int len,
                      pcallback pcb, const char *pline_head,
                      const char *pline_end) {
  int i;
  const char *const type[] = {
      "透明传输",
      "DL/T645-1997",
      "DL/T645-2007",
      "DL/T698.45",
  };

  pcb(pline_head);
  pcb("未抄读成功的从节点信息");
  pcb(pline_end);
  if (dir == 0)  //下行
  {
    CHK_APP_LEN(len, 3);
    sprintf(buf, "%s从节点起始序号[%02X %02X]:%d%s", pline_head, pin[0], pin[1],
            pin[0] | ((int)pin[1] << 8), pline_end);
    pcb(buf);
    sprintf(buf, "%s从节点数量[%02x]:%d%s", pline_head, pin[2], pin[2],
            pline_end);
    pcb(buf);
  } else  //上行
  {
    sprintf(buf, "%s从节点总数量[%02X %02X]:%d%s", pline_head, pin[0], pin[1],
            pin[0] | ((int)pin[1] << 8), pline_end);
    pcb(buf);
    sprintf(buf, "%s本次应答的从节点数量:%d%s", pline_head, pin[2], pline_end);
    pcb(buf);
    if (len < (pin[2] * 8 + 3)) {
      sprintf(buf, "%s输入报文长度不足解析失败!%s", pline_head, pline_end);
      pcb(buf);
      return -1;
    }

    for (i = 0; i < pin[2]; i++) {
      sprintf(buf, "%s从节点%d地址:[%02X %02X %02X %02X %02X %02X]%s",
              pline_head, i, pin[i * 8 + 3], pin[i * 8 + 4], pin[i * 8 + 5],
              pin[i * 8 + 6], pin[i * 8 + 7], pin[i * 8 + 8], pline_end);
      pcb(buf);

      sprintf(buf, "%s中继级别:%d%s", pline_head, pin[i * 8 + 9] & 0x0f,
              pline_end);
      pcb(buf);
      sprintf(buf, "%s侦听信号品质:%d%s", pline_head, pin[i * 8 + 9] >> 4,
              pline_end);
      pcb(buf);
      sprintf(buf, "%s相位[%d]:%s%s", pline_head, pin[i * 8 + 10] & 0x07,
              "(D8 D9 D10置\"1\"依次表示第1 2 3相)", pline_end);
      pcb(buf);
      sprintf(buf, "%s通信协议类型[%d]:%s%s", pline_head,
              (pin[i * 8 + 10] >> 3) & 0x07,
              (((pin[i * 8 + 10] >> 3) & 0x07) < 4)
                  ? type[(pin[i * 8 + 10] >> 3) & 0x07]
                  : "保留",
              pline_end);
      pcb(buf);
    }
  }

  return 0;
}

/**
 ******************************************************************************
 * @brief   输出主动注册的从节点信息解析字符串
 * @param[in]   dir         : 传输方向:1上行(模块->集中器)" 0下行(集中器->模块)
 * @param[in]  *pin         : 输入报文
 * @param[in]   len         : 应用层报文长度
 * @param[in]  *pcb         : 回调函数
 * @param[in]  *pline_head  : 每行起始填充字符串
 * @param[in]  *pline_end   : 每行结束填充字符串
 *
 * @return  0 : 解析成功
 * @return -1 : 解析失败
 ******************************************************************************
 */
static int AFN10_FN06(unsigned char dir, const unsigned char *pin, int len,
                      pcallback pcb, const char *pline_head,
                      const char *pline_end) {
  int i;
  const char *const type[] = {
      "透明传输",
      "DL/T645-1997",
      "DL/T645-2007",
      "DL/T698.45",
  };

  pcb(pline_head);
  pcb("主动注册的从节点信息");
  pcb(pline_end);
  if (dir == 0)  //下行
  {
    sprintf(buf, "%s从节点起始序号[%02X %02X]:%d%s", pline_head, pin[0], pin[1],
            pin[0] | ((int)pin[1] << 8), pline_end);
    pcb(buf);
    sprintf(buf, "%s从节点数量[%02x]:%d%s", pline_head, pin[2], pin[2],
            pline_end);
    pcb(buf);
  } else  //上行
  {
    sprintf(buf, "%s从节点总数量[%02X %02X]:%d%s", pline_head, pin[0], pin[1],
            pin[0] | ((int)pin[1] << 8), pline_end);
    pcb(buf);
    sprintf(buf, "%s本次应答的从节点数量:%d%s", pline_head, pin[2], pline_end);
    pcb(buf);
    if (len < (pin[2] * 8 + 3)) {
      sprintf(buf, "%s输入报文长度不足解析失败!%s", pline_head, pline_end);
      pcb(buf);
      return -1;
    }

    for (i = 0; i < pin[2]; i++) {
      sprintf(buf, "%s从节点%d地址:[%02X %02X %02X %02X %02X %02X]%s",
              pline_head, i, pin[i * 8 + 3], pin[i * 8 + 4], pin[i * 8 + 5],
              pin[i * 8 + 6], pin[i * 8 + 7], pin[i * 8 + 8], pline_end);
      pcb(buf);

      sprintf(buf, "%s中继级别:%d%s", pline_head, pin[i * 8 + 9] & 0x0f,
              pline_end);
      pcb(buf);
      sprintf(buf, "%s侦听信号品质:%d%s", pline_head, pin[i * 8 + 9] >> 4,
              pline_end);
      pcb(buf);
      sprintf(buf, "%s相位[%d]:%s%s", pline_head, pin[i * 8 + 10] & 0x07,
              "(D8 D9 D10置\"1\"依次表示第1 2 3相)", pline_end);
      pcb(buf);
      sprintf(buf, "%s通信协议类型[%d]:%s%s", pline_head,
              (pin[i * 8 + 10] >> 3) & 0x07,
              (((pin[i * 8 + 10] >> 3) & 0x07) < 4)
                  ? type[(pin[i * 8 + 10] >> 3) & 0x07]
                  : "保留",
              pline_end);
      pcb(buf);
    }
  }

  return 0;
}

#pragma pack(1)
typedef struct {
  uint8_t id[6];       /* 产品序号 */
  uint8_t type;        /* 模块类型 00保留,
                             01 单相电能表本地通信模块,
                             02 三相电能表本地通信模块,
                             03 I型采集器本地通信模块,
                             04 集中器I型本地通信单元
                             05 未知
                          */
  uint8_t chipId;      /* 芯片id */
  uint16_t fCode : 12; /* 长家代码 */
  uint16_t other : 4; /* 单位类别, 0 客户,1 公司总部,2 公司分部,3 省级电力公司,4
                         直属单位 ,>=5保留*/
  uint8_t magant; /* 管理单位 */
} nodeInfomation_t;

typedef struct {
  uint8_t type : 4; /* 节点类型 00 电表模块,01 采集器模块, 2-15保留*/
  uint8_t defNo3 : 3; /* 保留3bit */
  uint8_t upFlag : 1; /* 更新标识 */
  uint16_t fCode;     /* 厂商代码 */
  uint8_t idLen;      /* id长度 */
  uint8_t idType; /* id类型   00 组合格式, 01 BCD格式 ,02 bin格式, 03 ascii格式
                     ,>=04 保留 */
  uint8_t data[0]; /* 长度是idLen */
} s_staId_t;
typedef struct {
  uint16_t startSeq; /* 起始序号 */
  uint8_t count;     /* 请求数量 */
} AFN10_FN07_head_t;

typedef struct {
  uint16_t sCOunt; /* 从节点总数量 */
  uint8_t curCnt;  /* 本次应答数量 */
} AFN10_Fn07_up_head_t;

typedef struct {
  uint8_t mac[6];
  s_staId_t idHead;
} afn10_fn7_idInfo_t;

#pragma pack(0)

/**
 ******************************************************************************
 * @brief   输出查询从节点id号信息解析字符串
 * @param[in]   dir         : 传输方向:1上行(模块->集中器)" 0下行(集中器->模块)
 * @param[in]  *pin         : 输入报文
 * @param[in]   len         : 应用层报文长度
 * @param[in]  *pcb         : 回调函数
 * @param[in]  *pline_head  : 每行起始填充字符串
 * @param[in]  *pline_end   : 每行结束填充字符串
 *
 * @return  0 : 解析成功
 * @return -1 : 解析失败
 ******************************************************************************
 */
static int AFN10_FN07(unsigned char dir, const unsigned char *pin, int len,
                      pcallback pcb, const char *pline_head,
                      const char *pline_end) {
  unsed(dir);
  unsed(pin);
  unsed(len);
  unsed(pline_head);
  unsed(pline_end);
  unsed(pcb);
  pcb(pline_head);
  pcb("查询从节点ID号信息");
  pcb(pline_end);
  AFN10_FN07_head_t *head = NULL;
  AFN10_Fn07_up_head_t *upHead = NULL;
  afn10_fn7_idInfo_t *idInfo = NULL;
  nodeInfomation_t *nodeInfo = NULL;
  uint8_t *idinfomation= NULL;
  char fC[3] = {0};
  uint8_t cnt = 0;
  uint16_t dLen = 0, fCswap;
  if (dir == 0) {
    CHK_APP_LEN(len, sizeof(AFN10_FN07_head_t));
    head = (AFN10_FN07_head_t *)pin;
    sprintf(buf, "%s      从节点起始序号:%d\n      从节点数量:%d%s", pline_head,
            head->startSeq, head->count, pline_end);
    pcb(buf);
  } else {
    upHead = (AFN10_Fn07_up_head_t *)pin;

    sprintf(buf, "%s节点总数量:%d,本次应答数量%d %s", pline_head,
            upHead->sCOunt, upHead->curCnt, pline_end);
    pcb(buf);
    upHead++;
    idInfo = (afn10_fn7_idInfo_t *)upHead;
    upHead--;

    for (cnt = 0; cnt < upHead->curCnt; cnt++) {
      /* 打印表地址 */
      sprintf(buf, "%s      节点[%d]地址:[ %02x %02x %02x %02x %02x %02x ] %s",
              pline_head, cnt + 1, idInfo->mac[5], idInfo->mac[4],
              idInfo->mac[3], idInfo->mac[2], idInfo->mac[1], idInfo->mac[0],
              pline_end);
      pcb(buf);
      /* 节点类型 */
      switch (idInfo->idHead.type) {
        case 0:
          sprintf(buf, "%s      节点类型: 电表模块 %s", pline_head, pline_end);
          break;
        case 1:
          sprintf(buf, "%s      节点类型: 采集器模块 %s", pline_head,
                  pline_end);
          break;
        default:
          sprintf(buf, "%s      节点类型: (%d)保留 %s", pline_head,
                  idInfo->idHead.type, pline_end);
          break;
      }
      pcb(buf);

      /* 更新标识 */
      if (idInfo->idHead.upFlag == 0) {
        sprintf(buf, "%s      更新标识: 已更新 %s", pline_head, pline_end);
      } else {
        sprintf(buf, "%s      更新标识: 未更新 %s", pline_head, pline_end);
      }

      pcb(buf);

      /* 厂商代码 */
      fCswap = BSWAP_16(idInfo->idHead.fCode);
      memcpy(fC, &fCswap, sizeof(idInfo->idHead.fCode));
      sprintf(buf, "%s      厂商代码:%s %s", pline_head, fC, pline_end);
      pcb(buf);
      /* id长度 */
      dLen += idInfo->idHead.idLen;
      if (dLen > len) {
        break;
      }
      idinfomation = malloc(idInfo->idHead.idLen);
      memset(idinfomation, 0, idInfo->idHead.idLen);
      sprintf(buf, "%s      id长度:%0d %s", pline_head, idInfo->idHead.idLen,
              pline_end);
      pcb(buf);
      /* id类型 */
      switch (idInfo->idHead.idType) {
        case 0:
          sprintf(buf, "%s      id类型: 组合格式 %s", pline_head, pline_end);
          break;
        case 1:
          sprintf(buf, "%s      id类型: BCD格式 %s", pline_head, pline_end);
          break;
        case 2:
          sprintf(buf, "%s      id类型: BIN格式 %s", pline_head, pline_end);
          break;
        case 3:
          sprintf(buf, "%s      id类型: ASCII格式 %s", pline_head, pline_end);
          break;
        default:
          sprintf(buf, "%s      id类型: (%d)保留 %s", pline_head,
                  idInfo->idHead.idType, pline_end);
          break;
      }
      pcb(buf);
      /* 转换模块id信息 */
      memcpy(idinfomation, idInfo->idHead.data, idInfo->idHead.idLen);
      sprintf(buf, "%s      模块ID: ", pline_head);
      pcb(buf);
      for (uint8_t tCnt = 0; tCnt < idInfo->idHead.idLen; tCnt++,idinfomation++) {
        sprintf(buf+ tCnt*3, "%02x ",*idinfomation);
      }
      pcb(buf);


      free(idinfomation);
      idinfomation = NULL;
      nodeInfo = (nodeInfomation_t *)idInfo->idHead.data;
      if (idInfo->idHead.idLen == sizeof(nodeInfomation_t)) {
        /* 模块id */
        sprintf(buf, "\n%s      产品序号:[ %02x %02x %02x %02x %02x %02x ] %s",
                pline_head, nodeInfo->id[5], nodeInfo->id[4], nodeInfo->id[3],
                nodeInfo->id[2], nodeInfo->id[1], nodeInfo->id[0], pline_end);
        pcb(buf);
        /* 模块类型 */
        switch (nodeInfo->type) {
          case 1:
            sprintf(buf, "%s      模块类型: 单相电能表本地通信模块 %s",
                    pline_head, pline_end);
            break;
          case 2:
            sprintf(buf, "%s      模块类型: 三相电能表本地通信模块 %s",
                    pline_head, pline_end);
            break;
          case 3:
            sprintf(buf, "%s      模块类型: I型采集器本地通信模块 %s",
                    pline_head, pline_end);
            break;
          case 4:
            sprintf(buf, "%s      模块类型: 集中器I型本地通信单元 %s",
                    pline_head, pline_end);
            break;
          default:
            sprintf(buf, "%s      模块类型: 未知类型(%d) %s", pline_head,
                    nodeInfo->type, pline_end);
            break;
        }
        pcb(buf);
        /* 芯片id */
        sprintf(buf, "%s      模块芯片id: %04x %s", pline_head,
                nodeInfo->chipId, pline_end);
        pcb(buf);
        /* 厂家代码 */

        sprintf(buf, "%s      模块厂家代码: %04x %s", pline_head,
                nodeInfo->fCode, pline_end);
        pcb(buf);
        /* 单位类别 */
        switch (nodeInfo->other) {
          case 0:
            sprintf(buf, "%s      单位类别: 客户 %s", pline_head, pline_end);
            break;
          case 1:
            sprintf(buf, "%s      单位类别: 公司总部 %s", pline_head,
                    pline_end);
            break;
          case 2:
            sprintf(buf, "%s      单位类别: 公司分部 %s", pline_head,
                    pline_end);
            break;
          case 3:
            sprintf(buf, "%s      单位类别: 省级电力公司 %s", pline_head,
                    pline_end);
            break;
          case 4:
            sprintf(buf, "%s      单位类别: 直属单位 %s", pline_head,
                    pline_end);
            break;
          default:
            sprintf(buf, "%s      单位类别: (%02x)未知 %s", pline_head,
                    nodeInfo->other, pline_end);
            break;
        }
        pcb(buf);
        /* 管理单位 */
        sprintf(buf, "%s      管理单位: (%02x)未知 %s\n", pline_head,
                nodeInfo->magant, pline_end);
        pcb(buf);
      } else {
        sprintf(buf, "\n");
        pcb(buf);
      }

      idInfo =
          (afn10_fn7_idInfo_t *)(idInfo->idHead.data + idInfo->idHead.idLen);
    }
  }

  return 0;
}

/**
 ******************************************************************************
 * @brief   输出查询网络规模解析字符串
 * @param[in]   dir         : 传输方向:1上行(模块->集中器)" 0下行(集中器->模块)
 * @param[in]  *pin         : 输入报文
 * @param[in]   len         : 应用层报文长度
 * @param[in]  *pcb         : 回调函数
 * @param[in]  *pline_head  : 每行起始填充字符串
 * @param[in]  *pline_end   : 每行结束填充字符串
 *
 * @return  0 : 解析成功
 * @return -1 : 解析失败
 ******************************************************************************
 */
static int AFN10_FN09(unsigned char dir, const unsigned char *pin, int len,
                      pcallback pcb, const char *pline_head,
                      const char *pline_end) {
  unsed(dir);
  unsed(pin);
  unsed(len);
  unsed(pline_head);
  unsed(pline_end);
  unsed(pcb);

  pcb(pline_head);
  pcb("查询网络规模");
  pcb(pline_end);

  if (dir == 0)  //下行
  {
    CHK_APP_LEN(len, 0);
    sprintf(buf, "%s      无数据域 %s", pline_head, pline_end);
  } else  //上行
  {
    sprintf(buf, "%s 数据域解析未实现 %s", pline_head, pline_end);
  }
  pcb(buf);
  return 0;
}

#pragma pack(1)
typedef struct {
  uint16_t startSeq; /* 节点起始序号 */
  uint8_t count;     /* 节点数量 */
} dHead_t;
typedef struct {
  uint16_t nodeCount; /* 节点总数量 */
  uint16_t startSeq;  /* 节点起始序号 */
  uint8_t askCount;   /* 本次应答节点数量 */
} topHead_t;

typedef struct {
  uint8_t level : 4; /* 节点层级 0,1 ,2 ....*/
  uint8_t
      role : 4; /* 节点角色 0无效, 0x01末梢,0x02代理pco,0x03保留, 0x04主节点 */
} nodeInfo_t;

typedef struct {
  uint8_t mac[6];
  uint16_t nodeTEI; /*  */
  uint16_t proxyTEI;
  nodeInfo_t nodeInfo;
} nodeTop_t;

#pragma pack()
/**
 ******************************************************************************
 * @brief   输出查询网络拓扑信息解析字符串
 * @param[in]   dir         : 传输方向:1上行(模块->集中器)" 0下行(集中器->模块)
 * @param[in]  *pin         : 输入报文
 * @param[in]   len         : 应用层报文长度
 * @param[in]  *pcb         : 回调函数
 * @param[in]  *pline_head  : 每行起始填充字符串
 * @param[in]  *pline_end   : 每行结束填充字符串
 *
 * @return  0 : 解析成功
 * @return -1 : 解析失败
 ******************************************************************************
 */
static int AFN10_FN21(unsigned char dir, const unsigned char *pin, int len,
                      pcallback pcb, const char *pline_head,
                      const char *pline_end) {
  uint8_t cnt;
  topHead_t *top = NULL;
  nodeTop_t *node = NULL;
  unsed(len);
  pcb(pline_head);
  pcb("查询网络拓扑信息");
  pcb(pline_end);
  dHead_t *dHead = NULL;
  if (dir == 0)  //下行
  {
    dHead = (dHead_t *)pin;
    CHK_APP_LEN(len, sizeof(dHead_t));
    sprintf(buf, "%s      节点起始序号[%d]\n      节点数量[%d]%s", pline_head,
            dHead->startSeq, dHead->count, pline_end);
    pcb(buf);
  } else  //上行
  {
    top = (topHead_t *)pin;
    top++;
    node = (nodeTop_t *)top;
    top--;
    sprintf(buf, "%s节点总数量[%d]%s", pline_head, top->nodeCount, pline_end);
    pcb(buf);
    sprintf(buf, "%s节点起始序号[%d]%s", pline_head, top->startSeq, pline_end);
    pcb(buf);
    sprintf(buf, "%s本次应答节点数量[%d]%s", pline_head, top->askCount,
            pline_end);
    pcb(buf);
    if (top->askCount == 0) return 0;
    for (cnt = 0; cnt < top->askCount; cnt++, node++) {
      sprintf(buf, "%s节点[%d]地址:%02x %02x %02x %02x %02x %02x%s", pline_head,
              cnt, node->mac[0], node->mac[1], node->mac[2], node->mac[3],
              (char)node->mac[4], node->mac[5], pline_end);
      pcb(buf);
      sprintf(buf, "%s节点TEI[%02x]%s", pline_head, node->nodeTEI, pline_end);
      pcb(buf);
      sprintf(buf, "%s代理节点TEI[%02x]%s", pline_head, node->proxyTEI,
              pline_end);
      pcb(buf);

      sprintf(buf, "%s节点信息: 节点层级[%d]%s", pline_head,
              node->nodeInfo.level, pline_end);
      pcb(buf);

      switch (node->nodeInfo.role) {
        case 0:
          sprintf(buf, "%s节点角色[%d]: 无效%s", pline_head,
                  node->nodeInfo.role, pline_end);
          break;
        case 1:
          sprintf(buf, "%s节点角色[%d]: 末梢节点(sta)%s", pline_head,
                  node->nodeInfo.role, pline_end);
          break;
        case 2:
          sprintf(buf, "%s节点角色[%d]: 代理节点(pco)%s", pline_head,
                  node->nodeInfo.role, pline_end);
          break;
        case 4:
          sprintf(buf, "%s节点角色[%d]: 主节点(cco)%s", pline_head,
                  node->nodeInfo.role, pline_end);
          break;
        case 3:
        default:
          sprintf(buf, "%s节点角色[%d]: 保留%s", pline_head,
                  node->nodeInfo.role, pline_end);
          break;
      }
      pcb(buf);
    }
  }

  return 0;
}
#pragma pack(1)
typedef struct {
  uint16_t startSeq; /* 起始序号 */
  uint8_t count;     /* 查询数量 */
} phase_t;

typedef struct {
  uint16_t nodeCount; /* 节点总数量 */
  uint16_t startSeq;  /* 起始序号 */
  uint8_t askCount;   /* 本次应答次数 */
} phaseUp_t;

typedef struct {
  uint8_t phaseA : 1; /* 0不支持或者识别中, 相位  1 = A ,2 = B, 4= C*/
  uint8_t phaseB : 1; /* 0不支持或者识别中, 相位  1 = A ,2 = B, 4= C*/
  uint8_t phaseC : 1; /* 0不支持或者识别中, 相位  1 = A ,2 = B, 4= C*/
  uint8_t meterType : 1; /* 电表类型*/
  uint8_t errorInfo : 1; /* 线路异常 0无异常, 1 异常, 单相表零火线反接,
                            三相表,逆序,断相,零火线反接 */
  uint8_t three : 3; /* 三相线序  */
  uint8_t defNo;     /* 备用  */
} phaseInfomation_t;

typedef struct {
  uint8_t mac[6];          /* 节点地址 */
  phaseInfomation_t phase; /* 节点相位 */
} phaseInfo_t;
#pragma pack()

/**
 ******************************************************************************
 * @brief   输出查询相线信息模解析字符串
 * @param[in]   dir         : 传输方向:1上行(模块->集中器)" 0下行(集中器->模块)
 * @param[in]  *pin         : 输入报文
 * @param[in]   len         : 应用层报文长度
 * @param[in]  *pcb         : 回调函数
 * @param[in]  *pline_head  : 每行起始填充字符串
 * @param[in]  *pline_end   : 每行结束填充字符串
 *
 * @return  0 : 解析成功
 * @return -1 : 解析失败
 ******************************************************************************
 */
static int AFN10_FN31(unsigned char dir, const unsigned char *pin, int len,
                      pcallback pcb, const char *pline_head,
                      const char *pline_end) {
  pcb(pline_head);
  pcb("查询相线信息");
  pcb(pline_end);
  uint8_t cnt = 0;
  phase_t *phaseInfo = NULL;
  phaseUp_t *phaseUpInfo = NULL;
  phaseInfo_t *nodePhase = NULL;
  if (dir == 0)  //下行
  {
    CHK_APP_LEN(len, 3);
    phaseInfo = (phase_t *)pin;
    sprintf(buf, "%s      节点起始序号:%d\n      节点数量:%d %s", pline_head,
            phaseInfo->startSeq, phaseInfo->count, pline_end);
    pcb(buf);

  } else  //上行
  {
    phaseUpInfo = (phaseUp_t *)pin;

    sprintf(buf, "%s 节点总数量:%d\n 节点起始序号:%d\n 本次应答节点数量:%d %s",
            pline_head, phaseUpInfo->nodeCount, phaseUpInfo->startSeq,
            phaseUpInfo->askCount, pline_end);
    pcb(buf);
    phaseUpInfo++;
    nodePhase = (phaseInfo_t *)phaseUpInfo;
    phaseUpInfo--;
    for (cnt = 0; cnt < phaseUpInfo->askCount; cnt++) {
      sprintf(buf, "%s 节点[%d]地址: %02x %02x %02x %02x %02x %02x %s",
              pline_head, cnt, nodePhase->mac[0], nodePhase->mac[1],
              nodePhase->mac[2], nodePhase->mac[3], nodePhase->mac[4],
              nodePhase->mac[5], pline_end);
      pcb(buf);
      /* 解析相位信息 */
      sprintf(buf, "%s 相位信息(0未接入,1接入): A[%d],B[%d],C[%d] %s",
              pline_head, nodePhase->phase.phaseA, nodePhase->phase.phaseB,
              nodePhase->phase.phaseC, pline_end);
      pcb(buf);
      if (nodePhase->phase.meterType == 0) {
        /* 单相 */
        sprintf(buf, "%s 电表类型:单相表 %s", pline_head, pline_end);
        pcb(buf);
        if (nodePhase->phase.errorInfo == 0) {
          sprintf(buf, "%s 线路异常: 无异常或不支持识别功能 %s", pline_head,
                  pline_end);
        } else {
          sprintf(buf, "%s 线路异常: 零火线反接 %s", pline_head, pline_end);
        }
        pcb(buf);
      } else if (nodePhase->phase.meterType == 1) {
        /* 三相 */
        sprintf(buf, "%s 电表类型:三相表 %s", pline_head, pline_end);
        pcb(buf);

        if (nodePhase->phase.errorInfo == 0) {
          sprintf(buf, "%s 线路异常: 无异常或不支持识别功能 %s", pline_head,
                  pline_end);
        } else {
          sprintf(buf, "%s 线路异常: 逆序,断相,零火线反接 %s", pline_head,
                  pline_end);
        }
        pcb(buf);
      }

      switch (nodePhase->phase.three) {
        case 0:
          sprintf(buf, "%s 相位相序: ABC(正常相序) %s", pline_head, pline_end);
          break;
        case 1:
          sprintf(buf, "%s 相位相序: ACB %s", pline_head, pline_end);
          break;
        case 2:
          sprintf(buf, "%s 相位相序: BAC %s", pline_head, pline_end);
          break;
        case 3:
          sprintf(buf, "%s 相位相序: BCA %s", pline_head, pline_end);
          break;
        case 4:
          sprintf(buf, "%s 相位相序: CAB %s", pline_head, pline_end);
          break;
        case 5:
          sprintf(buf, "%s 相位相序: CBA %s", pline_head, pline_end);
          break;
        case 6:
          sprintf(buf, "%s 相位相序: 零火线反接 %s", pline_head, pline_end);
          break;
        case 7:
          sprintf(buf, "%s 相位相序: 保留 %s", pline_head, pline_end);
          break;
      }
      pcb(buf);

      nodePhase++;
    }
  }

  return 0;
}

#pragma pack(1)

typedef struct {
  uint16_t startSeq; /* 节点起始序号 */
  uint8_t reqCount;  /* 节点数量 */
} sswDownNodeInfo_t;

typedef struct {
  uint8_t mac[6];
  uint8_t upRssi; /* 上行品质 */
  uint8_t doRssi; /* 下行品质 */
} sswUpNodeInfo_t;

typedef struct {
  uint16_t nodeCount; /* 节点总数量 */
  uint16_t startSeq;  /* 节点起始序号 */
  uint8_t askcount;   /* 应答节点数量 */
} sswUpInfo_t;

typedef struct {
} sswRssi_t;

#pragma pack()
/**
 ******************************************************************************
 * @brief   输出查询载波信道品质解析字符串
 * @param[in]   dir         : 传输方向:1上行(模块->集中器)" 0下行(集中器->模块)
 * @param[in]  *pin         : 输入报文
 * @param[in]   len         : 应用层报文长度
 * @param[in]  *pcb         : 回调函数
 * @param[in]  *pline_head  : 每行起始填充字符串
 * @param[in]  *pline_end   : 每行结束填充字符串
 *
 * @return  0 : 解析成功
 * @return -1 : 解析失败
 ******************************************************************************
 */
static int AFN10_FN32(unsigned char dir, const unsigned char *pin, int len,
                      pcallback pcb, const char *pline_head,
                      const char *pline_end) {
  pcb(pline_head);
  pcb("查询载波信道品质");
  pcb(pline_end);
  uint8_t cnt;
  sswDownNodeInfo_t *downInfo = NULL;
  sswUpInfo_t *upInfo = NULL;
  sswUpNodeInfo_t *upNodeInfo = NULL;
  if (dir == 0)  //下行
  {
    CHK_APP_LEN(len, sizeof(sswDownNodeInfo_t));
    downInfo = (sswDownNodeInfo_t *)pin;
    sprintf(
        buf,
        "%s 节点起始序号:%d, 节点数量:%d, 默认第一个为主节点,后续为从节点 %s",
        pline_head, downInfo->startSeq, downInfo->startSeq, pline_end);
    pcb(buf);

  } else  //上行
  {
    upInfo = (sswUpInfo_t *)pin;
    upInfo++;
    upNodeInfo = (sswUpNodeInfo_t *)upInfo;
    upInfo--;

    sprintf(buf, "%s 节点总数量:%d 节点起始序号:%d 本次应答数量:%d %s",
            pline_head, upInfo->nodeCount, upInfo->startSeq, upInfo->askcount,
            pline_end);
    pcb(buf);

    for (cnt = 0; cnt < upInfo->askcount; cnt++, upNodeInfo++) {
      sprintf(buf, "%s 节点[%d]地址: %02x %02x %02x %02x %02x %02x %s",
              pline_head, cnt, upNodeInfo->mac[0], upNodeInfo->mac[1],
              upNodeInfo->mac[2], upNodeInfo->mac[3], upNodeInfo->mac[4],
              upNodeInfo->mac[5], pline_end);
      pcb(buf);
      sprintf(buf, "%s 节点[%d]: 上行:%d 下行:%d %s", pline_head, cnt,
              upNodeInfo->upRssi, upNodeInfo->doRssi, pline_end);
      pcb(buf);
    }
  }

  return 0;
}

#pragma pack(1)
/*
  681700 43 00 00 5F 00 00 16
  10 80 04
  01 01 00 00 00 00 00
  01
  4F 16
*/
typedef struct {
  uint8_t devType; /* 1 抄控器
                      2 集中器本地通信单元(cco)
                      3 电表通信单元(sta)
                      4 中继器
                      5 II型采集器
                      6 I型采集器

                    */
  uint8_t desMac[6];
  uint8_t chipIdType; /*
                       1 芯片id
                       2 模块id
                      */
} AFN10_FN40_head_t;
#pragma pack(0)
/**
 ******************************************************************************
 * @brief   输出读取id信息解析字符串
 * @param[in]   dir         : 传输方向:1上行(模块->集中器)" 0下行(集中器->模块)
 * @param[in]  *pin         : 输入报文
 * @param[in]   len         : 应用层报文长度
 * @param[in]  *pcb         : 回调函数
 * @param[in]  *pline_head  : 每行起始填充字符串
 * @param[in]  *pline_end   : 每行结束填充字符串
 *
 * @return  0 : 解析成功
 * @return -1 : 解析失败
 ******************************************************************************
 */
static int AFN10_FN40(unsigned char dir, const unsigned char *pin, int len,
                      pcallback pcb, const char *pline_head,
                      const char *pline_end) {
  pcb(pline_head);
  pcb("读取id信息");
  pcb(pline_end);
  AFN10_FN40_head_t *head = NULL;
  if (dir == 0)  //下行
  {
    CHK_APP_LEN(len, sizeof(AFN10_FN40_head_t));

    head = (AFN10_FN40_head_t *)pin;

    switch (head->devType) {
      case 1:
        sprintf(buf, "%s      设备类型:抄控器 %s", pline_head, pline_end);
        break;
      case 2:
        sprintf(buf, "%s      设备类型:集中器本地通信单元 %s", pline_head,
                pline_end);
        break;
      case 3:
        sprintf(buf, "%s      设备类型:电表通信单元 %s", pline_head, pline_end);
        break;
      case 4:
        sprintf(buf, "%s      设备类型:中继器 %s", pline_head, pline_end);
        break;
      case 5:
        sprintf(buf, "%s      设备类型:II型采集器 %s", pline_head, pline_end);
        break;
      case 6:
        sprintf(buf, "%s      设备类型:I型采集器 %s", pline_head, pline_end);
        break;
      default:
        sprintf(buf, "%s      设备类型:未知设备-%d %s", pline_head,
                head->devType, pline_end);
        break;
    }
    pcb(buf);
    sprintf(buf, "%s      设备地址: %02x %02x %02x %02x %02x %02x  %s",
            pline_head, head->desMac[0], head->desMac[1], head->desMac[2],
            head->desMac[3], head->desMac[4], head->desMac[5], pline_end);
    pcb(buf);
    switch (head->chipIdType) {
      case 1:
        sprintf(buf, "%s      id类型:芯片id %s", pline_head, pline_end);
        break;
      case 2:
        sprintf(buf, "%s      id类型:模块id %s", pline_head, pline_end);
        break;
      default:
        sprintf(buf, "%s      id类型:未知id-%d %s", pline_head,
                head->chipIdType, pline_end);
        break;
    }
    pcb(buf);
  } else  //上行
  {
    sprintf(buf, "%s      数据域解析未实现 %s", pline_head, pline_end);
    pcb(buf);
  }

  return 0;
}

/**
 ******************************************************************************
 * @brief   输出查询网络规模解析字符串
 * @param[in]   dir         : 传输方向:1上行(模块->集中器)" 0下行(集中器->模块)
 * @param[in]  *pin         : 输入报文
 * @param[in]   len         : 应用层报文长度
 * @param[in]  *pcb         : 回调函数
 * @param[in]  *pline_head  : 每行起始填充字符串
 * @param[in]  *pline_end   : 每行结束填充字符串
 *
 * @return  0 : 解析成功
 * @return -1 : 解析失败
 ******************************************************************************
 */
static int AFN10_FN100(unsigned char dir, const unsigned char *pin, int len,
                       pcallback pcb, const char *pline_head,
                       const char *pline_end) {
  pcb(pline_head);
  pcb("查询网络规模");
  pcb(pline_end);
  if (dir == 0)  //下行
  {
    CHK_APP_LEN(len, 0);
    sprintf(buf, "%s      无数据域%s", pline_head, pline_end);
    pcb(buf);
  } else  //上行
  {
    CHK_APP_LEN(len, 2);
    sprintf(buf, "%s      网络规模[%02X %02X]:%d%s", pline_head, pin[0], pin[1],
            pin[0] | ((int)pin[1] << 8), pline_end);
    pcb(buf);
  }

  return 0;
}

/**
 ******************************************************************************
 * @brief   输出查询微功率无线从节点信息解析字符串
 * @param[in]   dir         : 传输方向:1上行(模块->集中器)" 0下行(集中器->模块)
 * @param[in]  *pin         : 输入报文
 * @param[in]   len         : 应用层报文长度
 * @param[in]  *pcb         : 回调函数
 * @param[in]  *pline_head  : 每行起始填充字符串
 * @param[in]  *pline_end   : 每行结束填充字符串
 *
 * @return  0 : 解析成功
 * @return -1 : 解析失败
 ******************************************************************************
 */
static int AFN10_FN101(unsigned char dir, const unsigned char *pin, int len,
                       pcallback pcb, const char *pline_head,
                       const char *pline_end) {
  unsed(pin);
  pcb(pline_head);
  pcb("查询微功率无线从节点信息");
  pcb(pline_end);
  if (dir == 0)  //下行
  {
    CHK_APP_LEN(len, 0);
    sprintf(buf, "%s      无数据域 %s", pline_head, pline_end);
    pcb(buf);
  } else  //上行
  {
    sprintf(buf, "%s      数据域解析未实现 %s", pline_head, pline_end);
    pcb(buf);
  }

  return 0;
}

#pragma pack(1)
typedef struct {
  uint16_t startSeq; /* 节点起始序号 */
  uint8_t count;     /* 节点数量 */
} sDownNode_t;

typedef struct {
  uint8_t mac[6];   /* mac */
  uint16_t macInfo; /* 从节点n信息 */
  uint8_t bootVer;  /* boot版本 */
  uint16_t softVer; /* 软件版本 */
} sUpNodeInfo_t;

#pragma pack()
/**
 ******************************************************************************
 * @brief   输出查询网络节点信息解析字符串
 * @param[in]   dir         : 传输方向:1上行(模块->集中器)" 0下行(集中器->模块)
 * @param[in]  *pin         : 输入报文
 * @param[in]   len         : 应用层报文长度
 * @param[in]  *pcb         : 回调函数
 * @param[in]  *pline_head  : 每行起始填充字符串
 * @param[in]  *pline_end   : 每行结束填充字符串
 *
 * @return  0 : 解析成功
 * @return -1 : 解析失败
 ******************************************************************************
 */
static int AFN10_FN102(unsigned char dir, const unsigned char *pin, int len,
                       pcallback pcb, const char *pline_head,
                       const char *pline_end) {
  unsed(len);
  unsed(pin);
  unsed(dir);
  unsed(pline_end);
  unsed(pline_head);
  pcb(pline_head);
  pcb("查询网络节点信息");
  pcb(pline_end);
  uint8_t cnt = 0;
  sDownNode_t *downInfo = NULL;
  sUpNodeInfo_t *upInfo = NULL;
  if (dir == 0)  //下行
  {
    CHK_APP_LEN(len, sizeof(sDownNode_t));
    downInfo = (sDownNode_t *)pin;
    sprintf(buf, "%s      节点起始序号:%d\n      节点数量:%d %s", pline_head,
            downInfo->startSeq, downInfo->count, pline_end);
    pcb(buf);
  } else  //上行
  {
    downInfo = (sDownNode_t *)pin;
    downInfo++;
    upInfo = (sUpNodeInfo_t *)downInfo;
    downInfo--;
    sprintf(buf, "%s 从节点总数量:%d, 应答节点数量:%d %s", pline_head,
            downInfo->startSeq, downInfo->count, pline_end);
    pcb(buf);

    for (cnt = 0; cnt < downInfo->count; cnt++) {
      sprintf(buf, "%s 节点[%d]地址: %02x %02x %02x %02x %02x %02x %s",
              pline_head, cnt, upInfo->mac[0], upInfo->mac[1], upInfo->mac[2],
              upInfo->mac[3], upInfo->mac[4], upInfo->mac[5], pline_end);
      pcb(buf);
      sprintf(buf, "%s 从节点%d信息:%02x, bootloader:%d, 软件版本:%d %s",
              pline_head, cnt, upInfo->macInfo, upInfo->bootVer,
              upInfo->softVer, pline_end);
      pcb(buf);
    }
  }

  return 0;
}

typedef struct {
  uint8_t count;
  uint8_t *data; /* datalen = count*6 */
} AFN10_FN103_head_t;

/**
 ******************************************************************************
 * @brief   输出查询指定节点信息解析字符串
 * @param[in]   dir         : 传输方向:1上行(模块->集中器)" 0下行(集中器->模块)
 * @param[in]  *pin         : 输入报文
 * @param[in]   len         : 应用层报文长度
 * @param[in]  *pcb         : 回调函数
 * @param[in]  *pline_head  : 每行起始填充字符串
 * @param[in]  *pline_end   : 每行结束填充字符串
 *
 * @return  0 : 解析成功
 * @return -1 : 解析失败
 ******************************************************************************
 */
static int AFN10_FN103(unsigned char dir, const unsigned char *pin, int len,
                       pcallback pcb, const char *pline_head,
                       const char *pline_end) {
  unsed(len);
  unsed(pin);
  unsed(dir);
  unsed(pline_end);
  unsed(pline_head);
  pcb(pline_head);
  pcb("查询指定节点信息");
  pcb(pline_end);
  AFN10_FN103_head_t *dhead = NULL;
  uint8_t count = 0;
  uint8_t *index = NULL;
  if (dir == 0)  //下行
  {
    dhead = (AFN10_FN103_head_t *)pin;
    if (dhead->count == 0) {
      sprintf(buf, "%s      本次查询数量:0 %s", pline_head, pline_end);
      pcb(buf);
      return 0;
    } else {
      index = (uint8_t *)pin;
      sprintf(buf, "%s      本次查询数量:%d %s", pline_head, dhead->count,
              pline_end);
      pcb(buf);
      index++;
      for (count = 0; count < dhead->count; count++) {
        sprintf(buf, "%s      节点%d地址: %02x %02x %02x %02x %02x %02x  %s",
                pline_head, count, index[5], index[4], index[3], index[2],
                index[1], index[0], pline_end);
        pcb(buf);
        index += 6;
      }
    }

  } else  //上行
  {
    sprintf(buf, "%s      数据域解析未实现 %s", pline_head, pline_end);
    pcb(buf);
  }

  return 0;
}

/**
 ******************************************************************************
 * @brief   输出查询从节点(通信单元)信息(非芯片信息)解析字符串
 * @param[in]   dir         : 传输方向:1上行(模块->集中器)" 0下行(集中器->模块)
 * @param[in]  *pin         : 输入报文
 * @param[in]   len         : 应用层报文长度
 * @param[in]  *pcb         : 回调函数
 * @param[in]  *pline_head  : 每行起始填充字符串
 * @param[in]  *pline_end   : 每行结束填充字符串
 *
 * @return  0 : 解析成功
 * @return -1 : 解析失败
 ******************************************************************************
 */
static int AFN10_FN104(unsigned char dir, const unsigned char *pin, int len,
                       pcallback pcb, const char *pline_head,
                       const char *pline_end) {
  unsed(len);
  unsed(pin);
  unsed(dir);
  unsed(pline_end);
  unsed(pline_head);
  pcb(pline_head);
  pcb("查询从节点(通信单元)信息(非芯片信息)");
  pcb(pline_end);
  sDownNode_t *dHead = NULL;
  if (dir == 0)  //下行
  {
    CHK_APP_LEN(len, sizeof(sDownNode_t));
    dHead = (sDownNode_t *)pin;
    sprintf(buf, "%s      节点起始序号:%d\n      节点数量:%d %s", pline_head,
            dHead->startSeq, dHead->count, pline_end);
    pcb(buf);

  } else  //上行
  {
    sprintf(buf, "%s      数据域解析未实现 %s", pline_head, pline_end);
    pcb(buf);
  }

  return 0;
}

#pragma pack(1)
typedef struct {
  uint8_t meterAddr[6];  /* 表地址 */
  uint8_t frozenTime[6]; /* 冻结时间 */
  uint16_t startSeq;     /* 编号起始序号 */
  uint8_t count;         /* 本次查询编号数量 */
} AFN10_FN105_head_t;

#pragma pack(0)
/**
 ******************************************************************************
 * @brief   输出查询抄读曲线数据内容解析字符串
 * @param[in]   dir         : 传输方向:1上行(模块->集中器)" 0下行(集中器->模块)
 * @param[in]  *pin         : 输入报文
 * @param[in]   len         : 应用层报文长度
 * @param[in]  *pcb         : 回调函数
 * @param[in]  *pline_head  : 每行起始填充字符串
 * @param[in]  *pline_end   : 每行结束填充字符串
 *
 * @return  0 : 解析成功
 * @return -1 : 解析失败
 ******************************************************************************
 */
static int AFN10_FN105(unsigned char dir, const unsigned char *pin, int len,
                       pcallback pcb, const char *pline_head,
                       const char *pline_end) {
  unsed(len);
  unsed(pin);
  unsed(dir);
  unsed(pline_end);
  unsed(pline_head);
  pcb(pline_head);
  pcb("查询抄读曲线数据内容");
  AFN10_FN105_head_t *head = NULL;
  pcb(pline_end);
  if (dir == 0)  //下行
  {
    /*
      68
      1E 00
      43
      00 00 5F 00 00 23
      10 01 0D
      06 05 04 03 02 01
      07 06 05 04 03 02
      2C 01
      0A
      4A
      16

681E004300005F000023
10 01 0D
06 05 04 03 02 01
07 06 05 04 03 02
2C 01 0A
4A 16
    */
    CHK_APP_LEN(len, sizeof(AFN10_FN105_head_t));
    head = (AFN10_FN105_head_t *)pin;
    sprintf(buf,
            "%s      表地址: %02x %02x %02x %02x %02x %02x\n      "
            "冻结时间:%02x年%02x月%02x日 %02x时%02x分%02x秒\n      "
            "编号起始序号:%d\n      本次查询编号数量:%d %s",
            pline_head, head->meterAddr[5], head->meterAddr[4],
            head->meterAddr[3], head->meterAddr[2], head->meterAddr[1],
            head->meterAddr[0], head->frozenTime[5], head->frozenTime[4],
            head->frozenTime[3], head->frozenTime[2], head->frozenTime[1],
            head->frozenTime[0], head->startSeq, head->count, pline_end);
    pcb(buf);

  } else  //上行
  {
    sprintf(buf, "%s      数据域解析未实现 %s", pline_head, pline_end);
    pcb(buf);
  }

  return 0;
}

#pragma pack(1)
typedef struct {
  uint8_t NID[3];
  uint8_t mac[6];
} mNetInfo_t;

#pragma pack()
/**
 ******************************************************************************
 * @brief   输出查询多网络信息模解析字符串
 * @param[in]   dir         : 传输方向:1上行(模块->集中器)" 0下行(集中器->模块)
 * @param[in]  *pin         : 输入报文
 * @param[in]   len         : 应用层报文长度
 * @param[in]  *pcb         : 回调函数
 * @param[in]  *pline_head  : 每行起始填充字符串
 * @param[in]  *pline_end   : 每行结束填充字符串
 *
 * @return  0 : 解析成功
 * @return -1 : 解析失败
 ******************************************************************************
 */
static int AFN10_FN111(unsigned char dir, const unsigned char *pin, int len,
                       pcallback pcb, const char *pline_head,
                       const char *pline_end) {
  pcb(pline_head);
  pcb("查询多网络信息");
  uint8_t *pIndex = NULL;
  mNetInfo_t *mNet = NULL;
  uint8_t cnt;

  pcb(pline_end);
  if (dir == 0)  //下行
  {
    CHK_APP_LEN(len, 0);
    sprintf(buf, "%s      无数据域 %s", pline_head, pline_end);
    pcb(buf);
  } else  //上行
  {
    pIndex = (uint8_t *)pin;

    sprintf(buf, "%s多网络节点总数量:%d %s", pline_head, *pIndex, pline_end);
    pcb(buf);
    pIndex++;
    mNet = (mNetInfo_t *)pIndex++;

    for (cnt = 0; cnt < *pin; cnt++, mNet++) {
      sprintf(buf,
              "%s节点[%d]: 网络标识NID[%02x %02x %02x], 节点地址:[%02x %02x "
              "%02x %02x %02x %02x]%s",
              pline_head, cnt, mNet->NID[0], mNet->NID[1], mNet->NID[2],
              mNet->mac[0], mNet->mac[1], mNet->mac[2], mNet->mac[3],
              mNet->mac[4], mNet->mac[5], pline_end);
      pcb(buf);
    }
  }

  return 0;
}

#pragma pack(1)
typedef struct {
  uint16_t startSeq; /* 起始序号 */
  uint8_t count;     /* 节点数量 */
} sswIdInfo_t;

typedef struct {
  uint16_t nodeCount; /* 节点总数量 */
  uint16_t sTartSeq;  /* 起始序号 */
  uint8_t askCount;   /* 本次应答数量 */
} askInfo_t;

typedef struct {
  uint8_t head1;     /* 固定0x01 */
  uint8_t head2;     /* 固定0x02 */
  uint8_t head3;     /* 固定0x9c */
  uint8_t info[3];   /* 固定值 电科院代号 0x01c1fb */
  uint8_t type;      /* 设备类型 */
  uint16_t fCode;    /* 厂家代号 */
  uint16_t chipType; /* 芯片型号 */
  uint8_t devId[5];  /* 设备序列号 */
  uint8_t crc[8];    /* crc */
} sswChipInfo_t;

#pragma pack()

/**
 ******************************************************************************
 * @brief   输出查询HPLC芯片信息模解析字符串
 * @param[in]   dir         : 传输方向:1上行(模块->集中器)" 0下行(集中器->模块)
 * @param[in]  *pin         : 输入报文
 * @param[in]   len         : 应用层报文长度
 * @param[in]  *pcb         : 回调函数
 * @param[in]  *pline_head  : 每行起始填充字符串
 * @param[in]  *pline_end   : 每行结束填充字符串
 *
 * @return  0 : 解析成功
 * @return -1 : 解析失败
 ******************************************************************************
 */
static int AFN10_FN112(unsigned char dir, const unsigned char *pin, int len,
                       pcallback pcb, const char *pline_head,
                       const char *pline_end) {
  sswIdInfo_t *downData = NULL;
  askInfo_t *askInfo = NULL;
  sswChipInfo_t *nodeInfo = NULL;
  uint16_t dLen = 0;
  uint8_t cnt;
  pcb(pline_head);
  pcb("查询HPLC芯片信息");
  pcb(pline_end);
  if (dir == 0)  //下行
  {
    CHK_APP_LEN(len, 3);
    downData = (sswIdInfo_t *)pin;
    sprintf(buf, "%s      节点起始序号:%d\n      节点数量:%d %s", pline_head,
            downData->startSeq, downData->count, pline_end);
    pcb(buf);

  } else  //上行
  {
    /* 上行待处理 */
    askInfo = (askInfo_t *)pin;
    sprintf(buf, "%s节点总数量:%d 起始序号:%d 本次应答数量%d %s", pline_head,
            askInfo->nodeCount, askInfo->sTartSeq, askInfo->askCount,
            pline_end);
    pcb(buf);

    dLen = sizeof(askInfo_t);
    dLen += askInfo->askCount * sizeof(sswChipInfo_t);
    askInfo++;
    nodeInfo = (sswChipInfo_t *)askInfo;
    askInfo--;
    for (cnt = 0; cnt < askInfo->askCount; cnt++, nodeInfo++) {
      sprintf(buf, "%s节点[%d]----------- %s", pline_head, cnt, pline_end);
      pcb(buf);
      sprintf(buf, "%s byte1 byte2 byte3:[%02x %02x, %02x]  %s", pline_head,
              nodeInfo->head1, nodeInfo->head2, nodeInfo->head3, pline_end);
      pcb(buf);
      sprintf(buf, "%s 电科院信息:[%02x %02x, %02x]  %s", pline_head,
              nodeInfo->info[0], nodeInfo->info[1], nodeInfo->info[2],
              pline_end);
      pcb(buf);

      switch (nodeInfo->type) {
        case 1:
          sprintf(buf, "%s 设备类型: 抄控器 %s", pline_head, pline_end);
          break;
        case 2:
          sprintf(buf, "%s 设备类型: 集中器本地通信单元 %s", pline_head,
                  pline_end);
          break;
        case 3:
          sprintf(buf, "%s 设备类型: 电表通信单元 %s", pline_head, pline_end);
          break;
        case 4:
          sprintf(buf, "%s 设备类型: 中继器 %s", pline_head, pline_end);
          break;
        case 5:
          sprintf(buf, "%s 设备类型: II型采集器 %s", pline_head, pline_end);
          break;
        case 6:
          sprintf(buf, "%s 设备类型: I型采集器单元 %s", pline_head, pline_end);
          break;
        default:
          sprintf(buf, "%s 设备类型[%d]: 未知类型 %s", pline_head,
                  nodeInfo->type, pline_end);
          break;
      }
      pcb(buf);

      sprintf(buf, "%s 厂商代码:%04x %s", pline_head, nodeInfo->fCode,
              pline_end);
      pcb(buf);
      sprintf(buf, "%s 芯片型号:%04x %s", pline_head, nodeInfo->chipType,
              pline_end);
      pcb(buf);
      sprintf(buf, "%s 设备序列号:%02x %02x %02x %02x %02x %s", pline_head,
              nodeInfo->devId[0], nodeInfo->devId[1], nodeInfo->devId[2],
              nodeInfo->devId[3], nodeInfo->devId[4], pline_end);
      pcb(buf);
      sprintf(buf, "%s 校验码:%02x %02x %02x %02x %02x %02x %02x %02x %s",
              pline_head, nodeInfo->crc[0], nodeInfo->crc[1], nodeInfo->crc[2],
              nodeInfo->crc[3], nodeInfo->crc[4], nodeInfo->crc[5],
              nodeInfo->crc[6], nodeInfo->crc[7], pline_end);
      pcb(buf);
    }
  }
  return 0;
}

#pragma pack(1)
typedef struct {
  uint16_t startSeq; /* 起始序号 */
  uint8_t count;     /* 节点数量 */
} AFN10_FN150_head_t;

#pragma pack(0)
/**
 ******************************************************************************
 * @brief   输出查询cco内电能表信息解析字符串
 * @param[in]   dir         : 传输方向:1上行(模块->集中器)" 0下行(集中器->模块)
 * @param[in]  *pin         : 输入报文
 * @param[in]   len         : 应用层报文长度
 * @param[in]  *pcb         : 回调函数
 * @param[in]  *pline_head  : 每行起始填充字符串
 * @param[in]  *pline_end   : 每行结束填充字符串
 *
 * @return  0 : 解析成功
 * @return -1 : 解析失败
 ******************************************************************************
 */
static int AFN10_FN150(unsigned char dir, const unsigned char *pin, int len,
                       pcallback pcb, const char *pline_head,
                       const char *pline_end) {
  unsed(len);
  unsed(pin);
  unsed(dir);
  unsed(pline_end);
  unsed(pline_head);
  pcb(pline_head);
  pcb("查询cco内电能表信息");
  pcb(pline_end);
  AFN10_FN150_head_t *head = NULL;
  if (dir == 0)  //下行
  {
    CHK_APP_LEN(len, sizeof(AFN10_FN150_head_t));
    head = (AFN10_FN150_head_t *)pin;
    sprintf(buf, "%s      节点起始序号:%d\n      节点数量:%d %s", pline_head,
            head->startSeq, head->count, pline_end);
    pcb(buf);

  } else  //上行
  {
    sprintf(buf, "%s      数据域解析未实现 %s", pline_head, pline_end);
    pcb(buf);
  }

  return 0;
}

/**
 ******************************************************************************
 * @brief   输出路由查询解析字符串
 * @param[in]   dir         : 传输方向:1上行(模块->集中器)" 0下行(集中器->模块)
 * @param[in]  *pin         : 输入报文
 * @param[in]   len         : 应用层报文长度
 * @param[in]  *pcb         : 回调函数
 * @param[in]  *pline_head  : 每行起始填充字符串
 * @param[in]  *pline_end   : 每行结束填充字符串
 *
 * @return  0 : 解析成功
 * @return -1 : 解析失败
 ******************************************************************************
 */
int print_AFN10(unsigned char dir, const unsigned char *pin, int len,
                pcallback pcb, const char *pline_head, const char *pline_end) {
  unsigned char DT1 = pin[0];
  unsigned char DT2 = pin[1];
  int fn = get_clear_fn(&DT1, &DT2);

  switch (fn) {
    case 1:  //从节点数量
      return AFN10_FN01(dir, pin + 2, len - 2, pcb, pline_head, pline_end);
    case 2:  //从节点信息
      return AFN10_FN02(dir, pin + 2, len - 2, pcb, pline_head, pline_end);
    case 3:  //指定从节点的上一级中继路由信息
      return AFN10_FN03(dir, pin + 2, len - 2, pcb, pline_head, pline_end);
    case 4:  //路由运行状态
      return AFN10_FN04(dir, pin + 2, len - 2, pcb, pline_head, pline_end);
    case 5:  //未抄读成功的从节点信息
      return AFN10_FN05(dir, pin + 2, len - 2, pcb, pline_head, pline_end);
    case 6:  //主动注册的从节点信息
      return AFN10_FN06(dir, pin + 2, len - 2, pcb, pline_head, pline_end);
    case 7:  //查询从节点ID号信息
      return AFN10_FN07(dir, pin + 2, len - 2, pcb, pline_head, pline_end);
    case 9:  //查询网络规模
      return AFN10_FN09(dir, pin + 2, len - 2, pcb, pline_head, pline_end);
    case 21:  //查询网络拓扑信息
      return AFN10_FN21(dir, pin + 2, len - 2, pcb, pline_head, pline_end);
    case 31:  //查询相线信息
      return AFN10_FN31(dir, pin + 2, len - 2, pcb, pline_head, pline_end);
    case 32:  //查询信号品质
      return AFN10_FN32(dir, pin + 2, len - 2, pcb, pline_head, pline_end);
    case 40:  //读取ID信息
      return AFN10_FN40(dir, pin + 2, len - 2, pcb, pline_head, pline_end);
    case 100:  //查询网络规模
      return AFN10_FN100(dir, pin + 2, len - 2, pcb, pline_head, pline_end);
    case 101:  //查询微功率无线从节点信息
      return AFN10_FN101(dir, pin + 2, len - 2, pcb, pline_head, pline_end);
    case 102:  //查询网络节点信息
      return AFN10_FN102(dir, pin + 2, len - 2, pcb, pline_head, pline_end);
    case 103:  //查询指定节点信息
      return AFN10_FN103(dir, pin + 2, len - 2, pcb, pline_head, pline_end);
    case 104:  //查询从节点(通信单元)信息(非芯片信息)
      return AFN10_FN104(dir, pin + 2, len - 2, pcb, pline_head, pline_end);
    case 105:  //查询抄读曲线数据内容
      return AFN10_FN105(dir, pin + 2, len - 2, pcb, pline_head, pline_end);
    case 111:  //查询多网络信息
      return AFN10_FN111(dir, pin + 2, len - 2, pcb, pline_head, pline_end);
    case 112:  //查询HPLC芯片信息
      return AFN10_FN112(dir, pin + 2, len - 2, pcb, pline_head, pline_end);
    case 150:  //查询cco内电能表信息
      return AFN10_FN150(dir, pin + 2, len - 2, pcb, pline_head, pline_end);
    default:
      break;
  }

  pcb(pline_head);
  pcb("ERROR:不支持的FN!");
  pcb(pline_end);

  return -ERR_AFN_FN;
}

/*--------------------------------AFN10.c------------------------------------*/
